grammar RE;

options {
  output=AST;
}

tokens {
  REOR;
  RANGE;
  REAND;
  KLEENE;
  NOTKLEEN;
  SET;
  RE;
}
@header {
package compiler.antlr;
}
@lexer::header 
{
package compiler.antlr;
}

start 	: alternation EOF -> ^(RE alternation)
	;

alternation 
	: concat ('|' concat)* -> ^(REOR concat+)
	;
	
concat  : kleen+ -> ^(REAND kleen+)
	; 
	
kleen 
options { backtrack = true; }
	: lowterm '*' -> ^(KLEENE lowterm) 
	| lowterm -> ^(NOTKLEEN lowterm)
	;

lowterm : SYMBOL 
	| '('! alternation ')'! 
	| '['! set ']'! 
	;

set 	: setElem+ -> ^(SET setElem+)
	;

setElem	: (SYMBOL '..')=> range 
	| SYMBOL
	;

range	: SYMBOL '..' SYMBOL -> ^(RANGE SYMBOL SYMBOL)
	;

WHITESPACE : ( '\t' | /*spaces are not ignored*/ '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ;

SYMBOL     : ~('\\') ;	

CTRL_ESCP  : '\\|' { setText("|"); $type = SYMBOL; }	
	   | '\\*' { setText("*"); $type = SYMBOL; }	
	   | '\\"' { setText("\""); $type = SYMBOL; }	
	   | '\\(' { setText("("); $type = SYMBOL; }	
	   | '\\)' { setText(")"); $type = SYMBOL; }	
	   | '\\\\' { setText("\\"); $type = SYMBOL; }	
   	   | '\\[' { setText("["); $type = SYMBOL; }	
   	   | '\\]' { setText("]"); $type = SYMBOL; }	
  	   | '\\.' { setText("."); $type = SYMBOL; }	
	   ;
